package com.hns.its.persistence.jpa;

import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.QueryDslJpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;

import javax.persistence.EntityManager;
import java.io.Serializable;

public class DefaultRepositoryFactory extends JpaRepositoryFactory {

	private final EntityManager entityManager;

	public DefaultRepositoryFactory(EntityManager entityManager) {
		super(entityManager);
		this.entityManager = entityManager;
	}


	@Override
	protected Object getTargetRepository(RepositoryInformation information) {
		Class<?> repositoryInterface = information.getRepositoryInterface();
		JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());

		if (isQueryDslExecutor(repositoryInterface)) {
			return new QueryDslJpaRepository(entityInformation, entityManager);
		} else {
			return new GenericRepositoryImpl(entityInformation, entityManager, repositoryInterface);
																										
		}
	}

	@Override
	protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
		if (isQueryDslExecutor(metadata.getRepositoryInterface())) {
			return QueryDslJpaRepository.class;
		} else {
			return GenericRepositoryImpl.class;
		}
	}

	/**
	 * Returns whether the given repository interface requires a QueryDsl
	 * specific implementation to be chosen.
	 * 
	 * @param repositoryInterface
	 * @return
	 */
	private boolean isQueryDslExecutor(Class<?> repositoryInterface) {
		return QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
	}

}